package com.wust.modules.online.cgform.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;

import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import com.wust.modules.codegenerate.util.CodeUtil;
import com.wust.modules.online.config.exception.DBException;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import com.wust.common.api.vo.Result;
import com.wust.common.system.query.QueryGenerator;
import com.wust.common.system.util.JwtUtil;
import com.wust.common.util.oConvertUtils;
import com.wust.modules.codegenerate.database.DbReadTableUtil;
import com.wust.modules.online.cgform.entity.OnlCgformEnhanceJava;
import com.wust.modules.online.cgform.entity.OnlCgformEnhanceJs;
import com.wust.modules.online.cgform.entity.OnlCgformEnhanceSql;
import com.wust.modules.online.cgform.entity.OnlCgformHead;
import com.wust.modules.online.cgform.enums.CgformEnum;
import com.wust.modules.online.cgform.mapper.OnlCgformEnhanceJavaMapper;
import com.wust.modules.online.cgform.service.IOnlCgformHeadService;
import com.wust.modules.online.cgform.util.SqlSymbolUtil;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;


/**
 * @author wanheng
 */
@Slf4j
@Api
@RestController("onlCgformHeadController")
@RequestMapping({"/admin/cgform/head"})
public class OnlCgformHeadController {

    @Resource
    private IOnlCgformHeadService onlCgformHeadService;

    @Resource
    private OnlCgformEnhanceJavaMapper onlCgformEnhanceJavaMapper;

    private static final List<String> b = Lists.newArrayList("act_", "ext_act_", "design_", "onl_", "sys_", "qrtz_");

    private static String c;

    @GetMapping({"/list"})
    public Result<IPage<OnlCgformHead>> list(OnlCgformHead onlCgformHead, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {
        Result result = new Result();
        QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(onlCgformHead, request.getParameterMap());
        queryWrapper.orderByDesc("create_time");
        Page page = new Page((long) pageNo, (long) pageSize);
        IPage iPage = this.onlCgformHeadService.page(page, queryWrapper);
        if (onlCgformHead.getCopyType() != null && onlCgformHead.getCopyType() == 0) {
            this.onlCgformHeadService.initCopyState(iPage.getRecords());
        }

        result.setSuccess(true);
        result.setResult(iPage);
        return result;
    }


    @PostMapping({"/add"})
    public Result<OnlCgformHead> add(@RequestBody OnlCgformHead onlCgformHead) {
        Result result = new Result();

        try {
            this.onlCgformHeadService.save(onlCgformHead);
            result.success("添加成功！");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result.error500("操作失败");
        }

        return result;
    }


    @PutMapping({"/edit"})
    public Result<OnlCgformHead> edit(@RequestBody OnlCgformHead onlCgformHead) {
        Result result = new Result();
        OnlCgformHead oldOnlCgformHead = (OnlCgformHead) this.onlCgformHeadService.getById(onlCgformHead.getId());
        if (oldOnlCgformHead == null) {
            result.error500("未找到对应实体");
        } else {
            boolean b = this.onlCgformHeadService.updateById(onlCgformHead);
            if (b) {
                result.success("修改成功!");
            }
        }
        return result;
    }

    @DeleteMapping({"/delete"})
    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
        try {
            this.onlCgformHeadService.deleteRecordAndTable(id);
        } catch (DBException e) {
            return Result.error("删除失败" + e.getMessage());
        } catch (SQLException e) {
            return Result.error("删除失败" + e.getMessage());
        }

        return Result.ok("删除成功!");
    }

    @DeleteMapping({"/removeRecord"})
    public Result<?> removeRecord(@RequestParam(name = "id", required = true) String id) {
        try {
            this.onlCgformHeadService.deleteRecord(id);
        } catch (DBException e) {
            return Result.error("移除失败" + e.getMessage());
        } catch (SQLException e) {
            return Result.error("移除失败" + e.getMessage());
        }

        return Result.ok("移除成功!");
    }

    @DeleteMapping({"/deleteBatch"})
    public Result<OnlCgformHead> deleteBatch(@RequestParam(name = "ids", required = true) String ids, @RequestParam(name = "flag") String flag) {
        Result result = new Result();
        if (ids != null && !"".equals(ids.trim())) {
            this.onlCgformHeadService.deleteBatch(ids, flag);
            result.success("删除成功!");
        } else {
            result.error500("参数不识别！");
        }

        return result;
    }

    @GetMapping({"/queryById"})
    public Result<OnlCgformHead> queryById(@RequestParam(name = "id", required = true) String id) {
        Result result = new Result();
        OnlCgformHead onlCgformHead = (OnlCgformHead) this.onlCgformHeadService.getById(id);
        if (onlCgformHead == null) {
            result.error500("未找到对应实体");
        } else {
            result.setResult(onlCgformHead);
            result.setSuccess(true);
        }

        return result;
    }

    @GetMapping({"/queryByTableNames"})
    public Result<?> queryByTableNames(@RequestParam(name = "tableNames", required = true) String tableNames) {
        LambdaQueryWrapper<OnlCgformHead> lambdaQueryWrapper = new LambdaQueryWrapper();
        String[] tableNameList = tableNames.split(",");
        lambdaQueryWrapper.in(OnlCgformHead::getTableName, Arrays.asList(tableNameList));
        List list = this.onlCgformHeadService.list(lambdaQueryWrapper);
        return list == null ? Result.error("未找到对应实体") : Result.ok(list);
    }

    @PostMapping({"/enhanceJs/{code}"})
    public Result<?> addEnhanceJs(@PathVariable("code") String code, @RequestBody OnlCgformEnhanceJs onlCgformEnhanceJs) {
        try {
            onlCgformEnhanceJs.setCgformHeadId(code);
            this.onlCgformHeadService.saveEnhance(onlCgformEnhanceJs);
            return Result.ok("保存成功!");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("保存失败!");
        }
    }


    @GetMapping({"/enhanceJs/{code}"})
    public Result<?> getEnhanceJs(@PathVariable("code") String code, HttpServletRequest request) {
        try {
            String type = request.getParameter("type");
            OnlCgformEnhanceJs onlCgformEnhanceJs = this.onlCgformHeadService.queryEnhance(code, type);
            return onlCgformEnhanceJs == null ? Result.error("查询为空") : Result.ok(onlCgformEnhanceJs);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("查询失败!");
        }
    }


    @PutMapping({"/enhanceJs/{code}"})
    public Result<?> updateEnhanceJs(@PathVariable("code") String code, @RequestBody OnlCgformEnhanceJs onlCgformEnhanceJs) {
        try {
            onlCgformEnhanceJs.setCgformHeadId(code);
            this.onlCgformHeadService.editEnhance(onlCgformEnhanceJs);
            return Result.ok("保存成功!");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("保存失败!");
        }
    }

    @GetMapping({"/enhanceButton/{formId}"})
    public Result<?> getEnhanceButton(@PathVariable("formId") String formId, HttpServletRequest request) {
        try {
            List list = this.onlCgformHeadService.queryButtonList(formId);
            return list != null && list.size() != 0 ? Result.ok(list) : Result.error("查询为空");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("查询失败!");
        }
    }

    @PostMapping({"/enhanceSql/{formId}"})
    public Result<?> addEnhanceSql(@PathVariable("formId") String formId, @RequestBody OnlCgformEnhanceSql onlCgformEnhanceSql) {
        try {
            onlCgformEnhanceSql.setCgformHeadId(formId);
            this.onlCgformHeadService.saveEnhance(onlCgformEnhanceSql);
            return Result.ok("保存成功!");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("保存失败!");
        }
    }


    @GetMapping({"/enhanceSql/{formId}"})
    public Result<?> getEnhanceSql(@PathVariable("formId") String formId, HttpServletRequest request) {
        try {
            String buttonCode = request.getParameter("buttonCode");
            OnlCgformEnhanceSql onlCgformEnhanceSql = this.onlCgformHeadService.queryEnhanceSql(formId, buttonCode);
            return onlCgformEnhanceSql == null ? Result.error("查询为空") : Result.ok(onlCgformEnhanceSql);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("查询失败!");
        }
    }

    @PutMapping({"/enhanceSql/{formId}"})
    public Result<?> updateEnhanceSql(@PathVariable("formId") String formId, @RequestBody OnlCgformEnhanceSql onlCgformEnhanceSql) {
        try {
            onlCgformEnhanceSql.setCgformHeadId(formId);
            this.onlCgformHeadService.editEnhance(onlCgformEnhanceSql);
            return Result.ok("保存成功!");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("保存失败!");
        }
    }


    @PostMapping({"/enhanceJava/{formId}"})
    public Result<?> addEnhanceJava(@PathVariable("formId") String formId, @RequestBody OnlCgformEnhanceJava onlCgformEnhanceJava) {
        try {
            if (SqlSymbolUtil.isNotClass(onlCgformEnhanceJava)) {
                return Result.error("类实例化失败，请检查!");
            } else {
                onlCgformEnhanceJava.setCgformHeadId(formId);
                if (this.onlCgformHeadService.checkOnlyEnhance(onlCgformEnhanceJava)) {
                    this.onlCgformHeadService.saveEnhance(onlCgformEnhanceJava);
                    return Result.ok("保存成功!");
                } else {
                    return Result.error("保存失败,数据不唯一!");
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("保存失败!");
        }
    }


    @GetMapping({"/enhanceJava/{formId}"})
    public Result<?> getEnhanceJava(@PathVariable("formId") String formId, OnlCgformEnhanceJava onlCgformEnhanceJava) {
        try {
            onlCgformEnhanceJava.setCgformHeadId(formId);
            OnlCgformEnhanceJava enhanceJava = this.onlCgformHeadService.queryEnhanceJava(onlCgformEnhanceJava);
            if (enhanceJava == null) {
                onlCgformEnhanceJava.setCgJavaValue((String) null);
                return Result.ok(onlCgformEnhanceJava);
            } else {
                return Result.ok(enhanceJava);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("查询失败!");
        }
    }


    @PutMapping({"/enhanceJava/{formId}"})
    public Result<?> updateEnhanceJava(@PathVariable("formId") String formId, @RequestBody OnlCgformEnhanceJava onlCgformEnhanceJava) {
        try {
            if (SqlSymbolUtil.isNotClass(onlCgformEnhanceJava)) {
                return Result.error("类实例化失败，请检查!");
            } else {
                onlCgformEnhanceJava.setCgformHeadId(formId);
                if (this.onlCgformHeadService.checkOnlyEnhance(onlCgformEnhanceJava)) {
                    this.onlCgformHeadService.editEnhance(onlCgformEnhanceJava);
                    return Result.ok("保存成功!");
                } else {
                    return Result.error("保存失败,数据不唯一!");
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("保存失败!");
        }
    }

    @GetMapping({"/enhanceJavaByButtonCode/{formId}"})
    public Result<?> getEnhanceJavaByButtonCode(@PathVariable("formId") String formId, OnlCgformEnhanceJava onlCgformEnhanceJava) {
        try {
            LambdaQueryWrapper<OnlCgformEnhanceJava> onlCgformEnhanceJavaLambdaQueryWrapper = new LambdaQueryWrapper();
            onlCgformEnhanceJavaLambdaQueryWrapper.eq(OnlCgformEnhanceJava::getButtonCode, onlCgformEnhanceJava.getButtonCode());
            onlCgformEnhanceJavaLambdaQueryWrapper.eq(OnlCgformEnhanceJava::getCgformHeadId, formId);
            OnlCgformEnhanceJava onlCgformEnhanceJava1 = (OnlCgformEnhanceJava) this.onlCgformEnhanceJavaMapper.selectOne(onlCgformEnhanceJavaLambdaQueryWrapper);
            if (onlCgformEnhanceJava1 == null) {
                return Result.error("查询为空");
            } else {
                log.info("---------enhanceJavaByButtonCode-----------" + onlCgformEnhanceJava1.toString());
                return Result.ok(onlCgformEnhanceJava1);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("查询失败!");
        }
    }

    @GetMapping({"/queryTables"})
    public Result<?> queryTables(HttpServletRequest request) {
        String username = JwtUtil.getUserNameByToken(request);
        if (!"admin".equals(username)) {
            return Result.error("noadminauth");
        } else {
        new ArrayList();

        List list;
        try {
            list = DbReadTableUtil.getTableNames();
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
            return Result.error("同步失败，未获取数据库表信息");
        }

        SqlSymbolUtil.sort(list);
        List onlinetables = this.onlCgformHeadService.queryOnlinetables();
        list.removeAll(onlinetables);
        ArrayList arrayList = new ArrayList();
        Iterator iterator = list.iterator();

        while (iterator.hasNext()) {
            String s = (String) iterator.next();
            if (!this.startsWith(s)) {
                HashMap hashMap = new HashMap();
                hashMap.put("id", s);
                arrayList.add(hashMap);
            }
        }

        return Result.ok(arrayList);
        }
    }

    @PostMapping({"/transTables/{tbnames}"})
    public Result<?> transTables(@PathVariable("tbnames") String tbnames, HttpServletRequest request) {
        String username = JwtUtil.getUserNameByToken(request);
        if (!"admin".equals(username)) {
            return Result.error("noadminauth");
        } else
        if (oConvertUtils.isEmpty(tbnames)) {
            return Result.error("未识别的表名信息");
        } else if (c != null && c.equals(tbnames)) {
            return Result.error("不允许重复生成!");
        } else {
            c = tbnames;
            String[] tbnameList = tbnames.split(",");

            for (int i = 0; i < tbnameList.length; ++i) {
                if (oConvertUtils.isNotEmpty(tbnameList[i])) {
                    int count = this.onlCgformHeadService.count((Wrapper) (new LambdaQueryWrapper<OnlCgformHead>()).eq(OnlCgformHead::getTableName, tbnameList[i]));
                    if (count <= 0) {
                        log.info("[IP] [online数据库导入表]   --表名：" + tbnameList[i]);
                        this.onlCgformHeadService.saveDbTable2Online(tbnameList[i]);
                    }
                }
            }

            c = null;
            return Result.ok("同步完成!");
        }
    }

    @GetMapping({"/rootFile"})
    public Result<?> rootFile() {
        JSONArray jsonArray = new JSONArray();
        File[] listRoots = File.listRoots();
        File[] files = listRoots;
        int length = listRoots.length;

        for (int i = 0; i < length; ++i) {
            File file = files[i];
            JSONObject jsonObject = new JSONObject();
            if (file.isDirectory()) {
                System.out.println(file.getPath());
                jsonObject.put("key", file.getAbsolutePath());
                jsonObject.put("title", file.getPath());
                jsonObject.put("opened", false);
                JSONObject jsonObject1 = new JSONObject();
                jsonObject1.put("icon", "custom");
                jsonObject.put("scopedSlots", jsonObject1);
                jsonObject.put("isLeaf", file.listFiles() == null || file.listFiles().length == 0);
            }

            jsonArray.add(jsonObject);
        }

        return Result.ok(jsonArray);
    }

    @GetMapping({"/fileTree"})
    public Result<?> fileTree(@RequestParam(name = "parentPath", required = true) String parentPath) {
        JSONArray jsonArray = new JSONArray();
        File file = new File(parentPath);
        File[] listFiles = file.listFiles();
        File[] files = listFiles;
        int length = listFiles.length;

        for (int i = 0; i < length; ++i) {
            File file1 = files[i];
            if (file1.isDirectory() && oConvertUtils.isNotEmpty(file1.getPath())) {
                JSONObject jsonObject = new JSONObject();
                System.out.println(file1.getPath());
                jsonObject.put("key", file1.getAbsolutePath());
                jsonObject.put("title", file1.getPath().substring(file1.getPath().lastIndexOf(File.separator) + 1));
                jsonObject.put("isLeaf", file1.listFiles() == null || file1.listFiles().length == 0);
                jsonObject.put("opened", false);
                JSONObject jsonObject1 = new JSONObject();
                jsonObject1.put("icon", "custom");
                jsonObject.put("scopedSlots", jsonObject1);
                jsonArray.add(jsonObject);
            }
        }

        return Result.ok(jsonArray);
    }

    @GetMapping({"/tableInfo"})
    public Result<?> tableInfo(@RequestParam(name = "code", required = true) String code) {
        OnlCgformHead onlCgformHead = (OnlCgformHead) this.onlCgformHeadService.getById(code);
        if (onlCgformHead == null) {
            return Result.error("未找到对应实体");
        } else {
            HashMap hashMap = new HashMap();
            hashMap.put("main", onlCgformHead);
            if (onlCgformHead.getTableType() == 2) {
                String subTableStr = onlCgformHead.getSubTableStr();
                if (oConvertUtils.isNotEmpty(subTableStr)) {
                    ArrayList arrayList = new ArrayList();
                    String[] subTableStrs = subTableStr.split(",");
                    String[] subTableStrs1 = subTableStrs;
                    int length = subTableStrs.length;

                    for (int i = 0; i < length; ++i) {
                        String subTableStr1 = subTableStrs1[i];
                        LambdaQueryWrapper<OnlCgformHead> onlCgformHeadLambdaQueryWrapper = new LambdaQueryWrapper();
                        onlCgformHeadLambdaQueryWrapper.eq(OnlCgformHead::getTableName, subTableStr1);
                        OnlCgformHead onlCgformHead1 = (OnlCgformHead) this.onlCgformHeadService.getOne(onlCgformHeadLambdaQueryWrapper);
                        arrayList.add(onlCgformHead1);
                    }

                    Collections.sort(arrayList, new Comparator<OnlCgformHead>() {

                        @Override
                        public int compare(OnlCgformHead onlCgformHead1, OnlCgformHead onlCgformHead2) {
                            Integer tabOrderNum1 = onlCgformHead1.getTabOrderNum();
                            if (tabOrderNum1 == null) {
                                tabOrderNum1 = 0;
                            }

                            Integer tabOrderNum2 = onlCgformHead2.getTabOrderNum();
                            if (tabOrderNum2 == null) {
                                tabOrderNum2 = 0;
                            }

                            return tabOrderNum1.compareTo(tabOrderNum2);
                        }
                    });
                    hashMap.put("sub", arrayList);
                }
            }

            Integer tableType = onlCgformHead.getTableType();
            if ("Y".equals(onlCgformHead.getIsTree())) {
                tableType = 3;
            }

            List jspModelList = CgformEnum.getJspModelList(tableType);
            hashMap.put("jspModeList", jspModelList);
            hashMap.put("projectPath", CodeUtil.getProjectPath());
            return Result.ok(hashMap);
        }
    }

    @PostMapping({"/copyOnline"})
    public Result<?> copyOnline(@RequestParam(name = "code", required = true) String code) {
        try {
            OnlCgformHead onlCgformHead = (OnlCgformHead) this.onlCgformHeadService.getById(code);
            if (onlCgformHead == null) {
                return Result.error("未找到对应实体");
            }

            this.onlCgformHeadService.copyOnlineTableConfig(onlCgformHead);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return Result.ok();
    }

    private boolean startsWith(String s) {
        Iterator iterator = b.iterator();

        String s1;
        do {
            if (!iterator.hasNext()) {
                return false;
            }

            s1 = (String) iterator.next();
        } while (!s1.startsWith(s1) && !s1.startsWith(s1.toUpperCase()));

        return true;
    }
}
